fix: H2 natural-key upserts, shared MERGE base, PostgreSQL JSONB binding, @StormTest script splitting#165
Merged
Conversation
…erals The @stormtest script runner split statements with a bare split(";"), so a semicolon inside a line comment, block comment, string literal or quoted identifier broke every test class using the script. Statements are now split with a small scanner that skips those regions and drops comment-only fragments. A semicolon planted in test-schema.sql guards the integration path.
…dialects H2 cannot infer the type of a bare parameter in the projection of the MERGE source query and failed natural-key upserts with "Unknown data type". Each parameter is now cast to the H2 type matching how the ORM binds the value; foreign key columns resolve their per-column leaf type through the referenced key (including compound record keys). The six previously @disabled H2 upsert tests are re-enabled, with new coverage for dependent one-to-one entities (PK-is-FK) with temporal columns and compound foreign keys. The near-identical MERGE implementations of H2, Oracle and SQL Server are extracted into a shared MergeEntityRepositoryImpl with hooks for the dialect differences (cast type, source suffix, statement suffix, version expressions, insert clause). The source query now projects only declared columns — expanded foreign-relation columns were bound but never referenced — and identifier quoting is applied consistently in the update and bind-vars clauses.
@JSON converter output was bound with setString, which PostgreSQL rejects for json/jsonb columns ("column is of type jsonb but expression is of type character varying") — even though the documentation recommends JSONB columns. The JSON converters now wrap their serialized output in a JsonString marker, bound through a new SqlDialect.setParameter(JsonString) overload: the default binds as a plain string (unchanged behavior for other databases), while PostgreSQL binds an untyped parameter so the server casts it to the column's JSON type. The JPA template unwraps the marker and inline literal rendering quotes it like a string. New Testcontainers coverage exercises insert, update, ON CONFLICT upsert and batch upsert against real jsonb columns, plus tests for the JPA binding and inline literal paths.
45df2eb to
1b91e38
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four fixes:
@StormTestscript splitting — scripts were split on every;, so a semicolon inside a SQL comment, string literal, or quoted identifier broke all tests using the script. Now split with a comment/literal-aware scanner (9 new unit tests + an integration guard intest-schema.sql).H2 natural-key upserts — H2 cannot infer bare
?parameter types in the MERGE source query (Unknown data type), which is why six upsert tests sat@Disabled. Each parameter is now cast to the H2 type matching how the ORM binds the value (Instant/OffsetDateTime/ZonedDateTime→TIMESTAMPsince they bind asTimestamp;BigDecimal→DECFLOATto avoid scale-0 truncation; enums →VARCHAR; FK columns resolve per-column leaf types through the referenced key, including compound record keys). All six disabled tests re-enabled, plus new dependent one-to-one (+Instant) and compound-FK coverage.Shared
MergeEntityRepositoryImpl— H2, Oracle, and SQL Server each hand-rolled near-identical MERGE code. Now one base class in storm-core with hooks for the real differences (cast type,FROM DUAL, statement terminator, version expressions, insert clause). The source query projects only declared columns — expanded foreign-relation columns were bound but never referenced by ON/UPDATE/INSERT. Net −146 lines.@Json→ PostgreSQLjsonb— converter output was bound viasetString, which PostgreSQL rejects forjson/jsonbcolumns, contradicting the documented JSONB recommendation. Converters now emit aJsonStringmarker bound through aSqlDialect.setParameter(JsonString)overload (default: plain string, unchanged elsewhere; PostgreSQL: untyped parameter so the server casts). Covered by new Testcontainers tests against realjsonbcolumns (insert/update/ON CONFLICTupsert/batch) plus JPA-binding and inline-literal tests.Verification